package com.gcsoftware.gateway.trafficProcess;

import com.gcsoftware.gateway.confLoader.LoadGWCfgParam;
import com.gcsoftware.gateway.filters.http.handler.gwMainHandlerFilter;
import com.gcsoftware.gateway.redis.LoadXml2Redis;
import com.gcsoftware.gateway.redis.RedisUtils;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.HttpRequest;
import org.littleshoot.proxy.HttpFilters;
import org.littleshoot.proxy.HttpFiltersSource;
import org.littleshoot.proxy.HttpProxyServerBootstrap;
import org.littleshoot.proxy.impl.DefaultHttpProxyServer;
import org.littleshoot.proxy.impl.ThreadPoolConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;

/**
 * Created by yinpeng on 18/1/23.
 */
public class gatewayEntry
{
    private static final Logger log = LoggerFactory.getLogger(gatewayEntry.class);
    private static final String appName = "gaff-DataSecurityGateway";
    private static final String SERV_RESOLVER="resolver";

    public void start()
    {
        log.info("Initializing configurations…");
        LoadGWCfgParam cfgParam = LoadGWCfgParam.getInstance();
        new LoadXml2Redis().init();

        RedisUtils.getJedisPool();

        ThreadPoolConfiguration threadPoolConfiguration = new ThreadPoolConfiguration();
        threadPoolConfiguration.withAcceptorThreads(cfgParam.getAcceptor());
        threadPoolConfiguration.withClientToProxyWorkerThreads(cfgParam.getClientToProxy());
        threadPoolConfiguration.withProxyToServerWorkerThreads(cfgParam.getProxyToServer());

        InetSocketAddress inetSocketAddress = new InetSocketAddress(cfgParam.getLocalIP(), cfgParam.getLocalPort());
        InetSocketAddress serverAddr = new InetSocketAddress(cfgParam.getRemoteAddr(),cfgParam.getRemotePort());
        String remoteAddr = cfgParam.getRemoteAddr()+":"+cfgParam.getRemotePort();
         boolean reqResetAddrTmp = false;

        if(!cfgParam.getRemoteRedirectType().equals(SERV_RESOLVER))
        {
            reqResetAddrTmp = true;
        }

        final boolean reqResetAddr = reqResetAddrTmp;
        //.withConnectTimeout(connectTimeoutMs)
        //.withIdleConnectionTimeout(idleConnectionTimeoutSec)

        HttpProxyServerBootstrap DataSecurityGateway = DefaultHttpProxyServer.bootstrap()
                .withAddress(inetSocketAddress)
                .withThreadPoolConfiguration(threadPoolConfiguration)
                .withFiltersSource(new HttpFiltersSource() {
                    @Override
                    public HttpFilters filterRequest(HttpRequest originalRequest, ChannelHandlerContext channelHandlerContext) {
                        return new gwMainHandlerFilter(originalRequest, channelHandlerContext,remoteAddr, reqResetAddr);
                    }

                    @Override
                    public int getMaximumRequestBufferSizeInBytes() {
                        return cfgParam.getMaxRequestBufferSize();
                    }

                    @Override
                    public int getMaximumResponseBufferSizeInBytes() {
                        return cfgParam.getMaxResponseBufferSize();
                    }
                })
                .withAllowRequestToOriginServer(true)
                .withName(appName);

        //@todo mitm, connectTimeout, ChainProxyManager, IdleTimeout

        if(!reqResetAddr)
        {
            DataSecurityGateway.withServerResolver(new gatewayServResolver(serverAddr));
        }

        DataSecurityGateway.start();
    }
}
